﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using FreeGoo.GameEngine;
using FreeGoo.WpfRenderer.MouseCursor.WpfMouseCursorItems;

namespace FreeGoo.WpfRenderer.MouseCursor
{
    public class WpfMouseCursor
    {
        private readonly IList<WpfMouseCursorItem> _items = new List<WpfMouseCursorItem>();
        private Panel _renderTarget;
        private int _maxSize;
        private int _minSize;
        private int _pathSteps;
        private double _lastDraw;
        private double _lastUpdate;
        private Stopwatch _stopwatch = new Stopwatch();
        
        public WpfMouseCursor(Panel renderTarget, int maxSize, int minSize, int pathSteps)
        {
            RenderTarget = renderTarget;
            _maxSize = maxSize;
            _minSize = minSize;
            _pathSteps = pathSteps;
            _stopwatch.Start();
            RedrawInterval = 1000 / 100;
            UpdateInterval = 0;
            BuildGraphics();
        }

        public Panel RenderTarget
        {
            get
            {
                return _renderTarget;
            }

            set
            {
                ClearGraphics();
                _renderTarget = value;
                BuildGraphics();
            }
        }

        public int MaxSize
        {
            get
            {
                return _maxSize;
            }

            set
            {
                _maxSize = value;
                BuildGraphics();
            }
        }

        public int MinSize
        {
            get
            {
                return _minSize;
            }

            set
            {
                _minSize = value;
                BuildGraphics();
            }
        }

        public int PathSteps
        {
            get
            {
                return _pathSteps;
            }

            set
            {
                _pathSteps = value;
                BuildGraphics();
            }
        }

        public Point Position { get { return _items[0].Position; } }

        /// <summary>
        /// Measured in milliseconds, 40 means 25 redraws per second.
        /// </summary>
        public int RedrawInterval { get; set; }

        /// <summary>
        /// Measured in milliseconds, 40 means 25 updates per second
        /// </summary>
        public int UpdateInterval { get; set; }      

        public void UpdateCursorPosition()
        {
            if (_lastUpdate + UpdateInterval < _stopwatch.Elapsed.TotalMilliseconds)
            {
                DoUpdateCursorPosition();
            }

            if (_lastDraw + 10 < _stopwatch.Elapsed.TotalMilliseconds)
            {
                DrawCursor();
            }
        }

        protected void DoUpdateCursorPosition()
        {
            // Register the new position    
            Point position = CrossMouse.GetPosition(RenderTarget);

            if (!IsPositionOk(position))
            {
                position = _items[0].Position;
            }

            // Push down the position
            for (int i = _items.Count - 1; i > 0; i--)
            {
                _items[i].Position = _items[i - 1].Position;
            }

            _items[0].Position = position;

            _lastUpdate = _stopwatch.Elapsed.TotalMilliseconds;
        }
        
        protected void DrawCursor()
        {
            foreach (WpfMouseCursorItem item in _items)
            {
                item.Draw();
            }
            
            _lastDraw = _stopwatch.Elapsed.TotalMilliseconds;
        }

        protected void BuildGraphics()
        {
            ClearGraphics();
            if (_renderTarget == null)
            {
                return;
            }

            for (int i = 0; i < PathSteps; i++)
            {
                _items.Add(new WpfMouseCursorItemCircle(this, i));
            }
        }

        protected void ClearGraphics()
        {
            if (_renderTarget == null)
            {
                return;
            }

            foreach (WpfMouseCursorItem element in _items)
            {
                element.ClearGraphics();
            }

            _items.Clear();
        }

        private bool IsPositionOk(Point position)
        {
            if (position.X < 0)
            {
                return false;
            }

            if (position.Y < 0)
            {
                return false;
            }

            return true;
        }
    }
}
